package com.jx.lcs.util.export;

import java.io.IOException;
import java.io.OutputStream;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;

import com.jx.lcs.util.export.SheetDefination;

/**
 * excel 导出超类
 * <p>
 * 直接子类: <br/>
 * Excel4MapExporter、Excel4BeanExporter<T>
 * 
 * @author sunlt
 * @date 2015.07.14
 */
public abstract class ExcelExporter<T> {

  /**
   * 导出 excel
   * <p>
   * 只输出一个 sheet
   * 
   * @param defination sheet定义
   * @param out 输出目标
   * @throws IOException
   */
  public void export(SheetDefination<T> defination, OutputStream out) throws IOException {

    HSSFWorkbook workbook = null;
    try {
      workbook = new HSSFWorkbook();

      this.createSheet(workbook, defination);

      workbook.write(out);
    } finally {
      if (workbook != null) {
        workbook.close();
      }
    }

  }

  /**
   * 导出 excel
   * <p>
   * 传入多少个 SheetDefination 就会输出多少个 sheet
   * 
   * @param definations sheet定义集合
   * @param out 输出目标
   * @throws IOException
   */
  public void export(List<SheetDefination<T>> definations, OutputStream out) throws IOException {

    HSSFWorkbook workbook = null;
    try {
      workbook = new HSSFWorkbook();
      for (int i = 0; i < definations.size(); i++) {
        this.createSheet(workbook, definations.get(i));
      }

      workbook.write(out);
      out.flush();
      out.close();

    } finally {
      if (workbook != null) {
        workbook.close();
      }
    }

  }

  /**
   * 创建 sheet
   * 
   * @param workbook 工作簿
   * @param defination sheet定义
   */
  protected void createSheet(HSSFWorkbook workbook, SheetDefination<T> defination) {

    HSSFSheet sheet = workbook.createSheet(defination.getSheetTitle());
    sheet.setDefaultColumnWidth(15);

    // 渲染表头
    this.renderHeader(workbook, sheet, defination.getHeaders());

    // 渲染数据
    this.renderData(workbook, sheet, defination);

  }

  /**
   * 渲染表头
   * 
   * @param workbook 工作簿
   * @param sheet sheet单
   * @param headers 表头
   */
  protected void renderHeader(HSSFWorkbook workbook, HSSFSheet sheet, String[] headers) {

    HSSFRow headerRow = sheet.createRow(0);

    for (int i = 0; i < headers.length; i++) {
      HSSFCell cell = headerRow.createCell(i);
      cell.setCellStyle(this.createHeaderStyle(workbook));
      HSSFRichTextString text = new HSSFRichTextString(headers[i]);
      cell.setCellValue(text);
    }
  }

  /**
   * 构建表头样式
   * 
   * @param workbook 工作簿
   * @return 表头样式
   */
  protected HSSFCellStyle createHeaderStyle(HSSFWorkbook workbook) {

    HSSFCellStyle headerStyle = workbook.createCellStyle();
    headerStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
    headerStyle.setFillForegroundColor(HSSFColor.SKY_BLUE.index);
    headerStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
    headerStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
    headerStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
    headerStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
    headerStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);

    HSSFFont headerFont = workbook.createFont();
    headerFont.setColor(HSSFColor.BLACK.index);
    headerFont.setFontHeightInPoints((short) 12);
    headerFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);

    headerStyle.setFont(headerFont);

    return headerStyle;
  }

  /**
   * 渲染数据
   * 
   * @param workbook 工作簿
   * @param sheet 待渲染数据的sheet
   * @param defination sheet定义
   */
  protected abstract void renderData(HSSFWorkbook workbook, HSSFSheet sheet,
      SheetDefination<T> defination);

  /**
   * 构建数据样式
   * 
   * @param workbook 工作簿
   * @return 内容样式
   */
  protected HSSFCellStyle createDataStyle(HSSFWorkbook workbook) {
    // 数据内容样式
    HSSFCellStyle contentStyle = workbook.createCellStyle();
    contentStyle.setFillForegroundColor(HSSFColor.LIGHT_YELLOW.index);
    contentStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
    contentStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
    contentStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
    contentStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
    contentStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
    contentStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
    contentStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

    HSSFFont contentFont = workbook.createFont();
    contentFont.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);

    contentStyle.setFont(contentFont);

    return contentStyle;
  }

}
